﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Common.UnitTesting.TestClasses;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Runtime.Serialization;

namespace Common.UnitTesting
{
    /// <summary>
    /// Summary description for ModelTest
    /// </summary>
    [TestClass]
    public class ModelTest
    {
        public ModelTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void NotifyPropertyChangeAspect_InvokesPropertyChangedEvent_WhenChangingPropertyWithAttributeAttached()
        {
            const string validPropertyName = "TestIntegerProperty";
            var model = new TestModelWithAspectOnProperty();
            Assert.AreEqual(default(string), model.RecentPropertyChangedPropertyName);
            model.TestIntegerProperty += 2;
            Assert.AreEqual(validPropertyName, model.RecentPropertyChangedPropertyName);

        }

        [TestMethod]
        public void NotifyPropertyChangeAspect_InvokesPropertyChangedEvent_WhenChangingPropertyOfClassWithAttributeAttachedToThatClass()
        {
            const string validPropertyName = "TestIntegerProperty";
            var model = new TestModelWithAspectOnClass();
            Assert.AreEqual(default(string), model.RecentPropertyChangedPropertyName);
            model.TestIntegerProperty = 2;
            Assert.AreEqual(validPropertyName, model.RecentPropertyChangedPropertyName);

        }

        [TestMethod]
        public void NotifyPropertyChangeAspect_DoesNotStopSettingValue_WhenSettingNewValue()
        {
            var model = new TestModelWithAspectOnClass();
            const int newValue = 2;
            Assert.AreEqual(default(int), model.TestIntegerProperty);
            model.TestIntegerProperty = newValue;
            Assert.AreEqual(newValue, model.TestIntegerProperty);

        }

        [TestMethod]
        public void DataMemberAspect_AddsDataMemberToProperty_WhenAttachedToAClassWithThatProperty()
        {
            const string validPropertyName = "TestIntegerProperty";
            var model = new TestModelWithAspectOnClass();
            var property=model.GetType().GetProperty(validPropertyName);
            var isDataMemberDefined=property.IsDefined(typeof (DataMemberAttribute), false);
            Assert.IsTrue(isDataMemberDefined);

        }

        [TestMethod]
        public void DataMemberAspect_AddsDataMemberToProperty_WhenAttachedToABaseClassOfThatWithAProperty()
        {
            const string validPropertyName = "TestIntegerProperty";
            var model = new TestModelWithAspectOnClass();
            var property = model.GetType().GetProperty(validPropertyName);
            var isDataMemberDefined = property.IsDefined(typeof(DataMemberAttribute), false);
            Assert.IsTrue(isDataMemberDefined);

        }
    }
}
